package classpath

import (
	"os"
	"path/filepath"
)

type Classpath struct {
	// 启动类路径
	bootClasspath Entry
	// 扩展类路径
	extClasspath Entry
	// 用户类路径
	userClasspath Entry
}

func Parse(jreOption, cpOption string) *Classpath {
	cp := &Classpath{}
	// 使用-Xjre选项解析启动类路径和扩展类路径
	cp.parseBootAndExtClasspath(jreOption)
	// 使用-classpath/-cp解析用户类路径
	cp.parseUserClasspath(cpOption)
	return cp
}

// ReadClass 依次从启动类路径、扩展类路径、用户类路径中搜索Class文件
func (self *Classpath) ReadClass(className string) ([]byte, Entry, error) {
	className = className + ".class"
	if data, entry, err := self.bootClasspath.readClass(className); err == nil {
		return data, entry, err
	}
	if data, entry, err := self.extClasspath.readClass(className); err == nil {
		return data, entry, err
	}
	return self.userClasspath.readClass(className)
}

func (self *Classpath) parseBootAndExtClasspath(jreOption string) {
	jreDir := getJreDir(jreOption)
	// jre/lib.*
	jreLibPath := filepath.Join(jreDir, "lib", "*")
	self.bootClasspath = newWildcardEntry(jreLibPath)
	// jre/lib/ext/*
	jreExtPath := filepath.Join(jreDir, "lib", "ext", "*")
	self.extClasspath = newWildcardEntry(jreExtPath)
}

/**
 * @Description:    获取jre目录
 * @param jreOption 用户输入的-Xjre参数
 * @return string   jre目录路径
 */
func getJreDir(jreOption string) string {
	// 优先使用用户输入的-Xjre路径
	if jreOption != "" && exists(jreOption) {
		return jreOption
	}
	// 其次在当前目录下寻找jre目录
	if exists("./jre") {
		return "./jre"
	}
	// 最后尝试寻找系统环境变量
	if jh := os.Getenv("JAVA_HOME"); jh != "" {
		return filepath.Join(jh, "jre")
	}
	panic("找不到JRE目录")
}

/**
 * @Description: 判断路径是否存在
 * @param path   路径
 * @return bool  是否存在
 */
func exists(path string) bool {
	if _, err := os.Stat(path); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

/**
 * @Description: 解析用户类路径
 * @receiver self
 * @param cpOption
 */
func (self *Classpath) parseUserClasspath(cpOption string) {
	// 用户未指定，则默认当前目录
	if cpOption == "" {
		cpOption = "."
	}
	self.userClasspath = newEntry(cpOption)
}
